﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace EIA.SLClient.Utility.Controls
{
    public partial class EditableTreeControl : UserControl
    {
        public EditableTreeControl()
        {
            InitializeComponent();
            this.TreeViewMain.ItemsSource = RootNodes;
            this.Loaded += (s, e) =>
            {
                AsyncUtils.DelayExcuteOnUIDispatcher(() =>
                {
                    InitialExpend();
                    AsyncUtils.DelayExcuteOnUIDispatcher(() =>
                    {
                        SetVisualSelectItem();
                    }, 100);
                }, 100);
            };
        }

        private void InitialExpend()
        {
            int newValue = this.ExpendDepth;
            if (this.RootNodes != null)
            {
                this.TreeViewMain.ExpandToDepth(newValue);
            }
        }

        private void SetVisualSelectItem()
        {
            if (this.TreeViewMain.SelectedItem != SelectedNode)
            {
                if (SelectedNode == null) this.TreeViewMain.ClearSelection();
                else this.TreeViewMain.SelectItem(SelectedNode);
            }
        }

        #region RootNodes (DependencyProperty)

        /// <summary>
        /// 根节点集合
        /// </summary>
        public ObservableCollection<TreeNode> RootNodes
        {
            get { return (ObservableCollection<TreeNode>)GetValue(RootNodesProperty); }
            set { SetValue(RootNodesProperty, value); }
        }
        public static readonly DependencyProperty RootNodesProperty =
            DependencyProperty.Register("RootNodes", typeof(ObservableCollection<TreeNode>), typeof(EditableTreeControl),
            new PropertyMetadata(new ObservableCollection<TreeNode>(), new PropertyChangedCallback(OnRootNodesChanged)));

        private static void OnRootNodesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            ObservableCollection<TreeNode> newValue = (ObservableCollection<TreeNode>)args.NewValue;
            source.TreeViewMain.ItemsSource = newValue;

            AsyncUtils.DelayExcuteOnUIDispatcher(() =>
            {
                source.InitialExpend();
            }, 100);
        }

        #endregion

        #region ExpendDepth (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public int ExpendDepth
        {
            get { return (int)GetValue(ExpendDepthProperty); }
            set { SetValue(ExpendDepthProperty, value); }
        }
        public static readonly DependencyProperty ExpendDepthProperty =
            DependencyProperty.Register("ExpendDepth", typeof(int), typeof(EditableTreeControl),
            new PropertyMetadata(0, new PropertyChangedCallback(OnExpendDepthChanged)));

        private static void OnExpendDepthChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            int newValue = (int)args.NewValue;
            source.InitialExpend();
        }

        #endregion

        #region SelectedNode (DependencyProperty)

        /// <summary>
        /// 选中的节点
        /// </summary>
        public TreeNode SelectedNode
        {
            get { return (TreeNode)GetValue(SelectedNodeProperty); }
            set { SetValue(SelectedNodeProperty, value); }
        }
        public static readonly DependencyProperty SelectedNodeProperty =
            DependencyProperty.Register("SelectedNode", typeof(TreeNode), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedNodeChanged)));

        private static void OnSelectedNodeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            TreeNode newValue = (TreeNode)args.NewValue;
            TreeNode oldValue = (TreeNode)args.OldValue;

            source.SetVisualSelectItem();
            var data = (newValue != null ? newValue.Data : null);
            if (source.SelectedData != data)
            {
                source.SelectedData = data;
            }
        }

        #endregion

        #region SelectedData (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public object SelectedData
        {
            get { return (object)GetValue(SelectedDataProperty); }
            set { SetValue(SelectedDataProperty, value); }
        }
        public static readonly DependencyProperty SelectedDataProperty =
            DependencyProperty.Register("SelectedData", typeof(object), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedDataChanged)));

        private static void OnSelectedDataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            object newValue = (object)args.NewValue;

            if (newValue == null && source.SelectedNode == null) return;

            if (newValue == null)
            {
                source.SelectedNode = null;
            }
            else
            {
                if (source.SelectedNode != null && newValue.Equals(source.SelectedNode.Data)) return;
                TreeNode node = TreeNode.FindNode(source.RootNodes, newValue);
                source.SelectedNode = node;
            }
        }

        #endregion


        #region AddCommand (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public ICommand AddCommand
        {
            get { return (ICommand)GetValue(AddCommandProperty); }
            set { SetValue(AddCommandProperty, value); }
        }
        public static readonly DependencyProperty AddCommandProperty =
            DependencyProperty.Register("AddCommand", typeof(ICommand), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnAddCommandChanged)));

        private static void OnAddCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            ICommand newValue = (ICommand)args.NewValue;
        }

        #endregion

        #region DeleteCommand (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public ICommand DeleteCommand
        {
            get { return (ICommand)GetValue(DeleteCommandProperty); }
            set { SetValue(DeleteCommandProperty, value); }
        }
        public static readonly DependencyProperty DeleteCommandProperty =
            DependencyProperty.Register("DeleteCommand", typeof(ICommand), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnDeleteCommandChanged)));

        private static void OnDeleteCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            ICommand newValue = (ICommand)args.NewValue;
        }

        #endregion

        #region EditCommand (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public ICommand EditCommand
        {
            get { return (ICommand)GetValue(EditCommandProperty); }
            set { SetValue(EditCommandProperty, value); }
        }
        public static readonly DependencyProperty EditCommandProperty =
            DependencyProperty.Register("EditCommand", typeof(ICommand), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnEditCommandChanged)));

        private static void OnEditCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            ICommand newValue = (ICommand)args.NewValue;
        }

        #endregion

        #region DragDropCommand (DependencyProperty)

        /// <summary>
        /// 该依赖属性的描述
        /// </summary>
        public ICommand DragDropCommand
        {
            get { return (ICommand)GetValue(DragDropCommandProperty); }
            set { SetValue(DragDropCommandProperty, value); }
        }
        public static readonly DependencyProperty DragDropCommandProperty =
            DependencyProperty.Register("DragDropCommand", typeof(ICommand), typeof(EditableTreeControl),
            new PropertyMetadata(null, new PropertyChangedCallback(OnDragDropCommandChanged)));

        private static void OnDragDropCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            // 获取自身的引用
            EditableTreeControl source = (EditableTreeControl)sender;

            // 处理逻辑
            ICommand newValue = (ICommand)args.NewValue;
        }

        #endregion

        private void ShowContextMenu(MouseButtonEventArgs e)
        {
            e.Handled = true;
            if (SelectedNode == null)
            {
                EditButton.Visibility = System.Windows.Visibility.Collapsed;
                DeleteButton.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                EditButton.Visibility = System.Windows.Visibility.Visible;
                DeleteButton.Visibility = System.Windows.Visibility.Visible;
            }
            Point p = e.GetPosition(this);
            ContextMenu.Visibility = Visibility.Visible;
            ContextMenu.IsOpen = true;
            ContextMenu.SetValue(Canvas.LeftProperty, (double)p.X);
            ContextMenu.SetValue(Canvas.TopProperty, (double)p.Y);
        }

        private void HideContextMenu()
        {
            ContextMenu.Visibility = Visibility.Collapsed;
            ContextMenu.IsOpen = false;
        }

        private void TreeViewMain_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        private void TreeViewMain_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (sender is TextBlock)
            {
                SelectedNode = (TreeNode)((sender as TextBlock).DataContext);
                //TreeViewMain.SelectItem(SelectedNode);
            }
            else
            {
                SelectedNode = null;
                //TreeViewMain.ClearSelection();
            }

            ShowContextMenu(e);
        }

        private void TreeViewMain_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            HideContextMenu();
        }

        private void TreeViewMain_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            //TreeNode newValue = (TreeNode)e.NewValue;
            //TreeNode oldValue = (TreeNode)e.OldValue;
            //if (oldValue != null)
            //{
            //    SetTemplateForTreeNode(oldValue, "ViewDataTemplate");
            //}
            //if (newValue != null)
            //{
            //    SetTemplateForTreeNode(newValue, "OptDataTemplate");
            //}
            SelectedNode = e.NewValue as TreeNode;
        }

        bool _mouse_leaved = true;
        private void TreeViewMain_MouseLeave(object sender, MouseEventArgs e)
        {
            _mouse_leaved = true;
        }

        private void TreeViewMain_MouseEnter(object sender, MouseEventArgs e)
        {
            _mouse_leaved = false;
        }

        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            if (AddCommand != null)
            {
                AddCommand.Execute(SelectedNode);
            }

            //TreeNode newNode = new TreeNode() { Text = "节点" };

            //if (SelectedNode != null)
            //{
            //    SelectedNode.Children.Add(newNode);
            //}
            //else
            //{
            //    if (RootNodes != null)
            //    {
            //        RootNodes.Add(newNode);
            //    }
            //    else
            //    {
            //        RootNodes = new ObservableCollection<TreeNode>();
            //        RootNodes.Add(newNode);
            //    }
            //}

            HideContextMenu();
        }

        private void EditButton_Click(object sender, RoutedEventArgs e)
        {
            if (EditCommand != null)
            {
                EditCommand.Execute(SelectedNode);
            }

            //TreeViewItem selectedTreeViewItem =
            //    TreeViewExtensions.GetContainerFromItem(TreeViewMain, SelectedNode);

            HideContextMenu();
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            if (DeleteCommand != null)
            {
                DeleteCommand.Execute(SelectedNode);
            }

            //TreeViewItem selectedTreeViewItem =
            //    TreeViewExtensions.GetContainerFromItem(TreeViewMain, SelectedNode);

            //if (selectedTreeViewItem != null)
            //{
            //    TreeViewItem selectedTreeViewItemParent =
            //        TreeViewExtensions.GetParentTreeViewItem(selectedTreeViewItem);

            //    if (selectedTreeViewItemParent != null)
            //    {
            //        TreeNode seleactedParentNode = (TreeNode)selectedTreeViewItemParent.DataContext;
            //        seleactedParentNode.Children.Remove(SelectedNode);
            //    }
            //    else
            //    {
            //        RootNodes.Remove(SelectedNode);
            //    }
            //}

            HideContextMenu();
        }

        private void TreeViewDragDropTarget_ItemDroppedOnSource(object sender, Microsoft.Windows.DragEventArgs e)
        {
            try
            {
                TreeNode node = (TreeNode)(((System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Selection>)(((System.Collections.ObjectModel.SelectionCollection)(((System.Windows.Controls.ItemDragEventArgs)(((Microsoft.Windows.DataObject)(e.Data)).GetData(typeof(System.Windows.Controls.ItemDragEventArgs)))).Data))))[0].Item);
                AsyncUtils.DelayExcuteOnUIDispatcher(() =>
                {
                    var parent = node.GetParent(RootNodes);//GetParentNode2(node, null); 
                    TreeViewMain.SelectItem(node);
                    if (DragDropCommand != null)
                    {
                        DragDropCommand.Execute(new Tuple<TreeNode, TreeNode>(node, parent));
                    }
                }, 0);
            }
            catch
            {
            }
        }

        private void TreeViewDragDropTarget_ItemDroppedOnTarget(object sender, ItemDragEventArgs e)
        {
            try
            {
                TreeNode node = (TreeNode)(((System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Selection>)(e.Data))[0].Item);
                AsyncUtils.DelayExcuteOnUIDispatcher(() =>
                {
                    var c = RootNodes.ToArray();
                    var parent = node.GetParent(RootNodes); //GetParentNode2(node, null);
                    if (parent != null) TreeViewMain.GetContainerFromItem(parent).IsExpanded = true;
                    TreeViewMain.SelectItem(node);
                    if (DragDropCommand != null)
                    {
                        DragDropCommand.Execute(new Tuple<TreeNode, TreeNode>(node, parent));
                    }
                }, 0);
            }
            catch
            {
            }
        }

        //private TreeNode GetParentNode2(TreeNode node, TreeNode r)
        //{
        //    ObservableCollection<TreeNode> nodes = r == null ? RootNodes : r.Children;
        //    if (nodes.Contains(node))
        //    {
        //        return r;
        //    }
        //    else if (nodes != null && nodes.Count > 0)
        //    {
        //        for (int i = 0; i < nodes.Count; i++)
        //        {
        //            var s = GetParentNode2(node, nodes[i]);
        //            if (s != null) return s;
        //        }
        //        return null;
        //    }
        //    else
        //    {
        //        return null;
        //    }
        //}

        //private TreeNode GetParentNode(TreeNode node)
        //{
        //    TreeViewItem selectedTreeViewItem =
        //        TreeViewExtensions.GetContainerFromItem(TreeViewMain, node);

        //    if (selectedTreeViewItem != null)
        //    {
        //        TreeViewItem selectedTreeViewItemParent =
        //            TreeViewExtensions.GetParentTreeViewItem(selectedTreeViewItem);

        //        if (selectedTreeViewItemParent != null)
        //        {
        //            return (TreeNode)selectedTreeViewItemParent.DataContext;
        //        }
        //    }
        //    return null;
        //}

        //
        private void SetTemplateForTreeNode(TreeNode node, String templateName)
        {
            HierarchicalDataTemplate hdt = (HierarchicalDataTemplate)Resources[templateName];
            TreeViewItem selectedTreeViewItem =
                TreeViewExtensions.GetContainerFromItem(TreeViewMain, node);

            if (selectedTreeViewItem != null)
                selectedTreeViewItem.HeaderTemplate = hdt;
        }
    }
}
